package fr.nekloth.android.hinode;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import uk.me.jstott.coordconv.LatitudeLongitude;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.DialogInterface.OnClickListener;
import android.content.res.Resources;
import android.graphics.Typeface;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;

import org.acra.ErrorReporter;


public class coordinatesActivity extends Activity {

	public static int COORDS_MENU_CHOICE_GPS_LOCATION = 0;
	public static int COORDS_MENU_CHOICE_SET_LOCATION = 1;
    //Third line is empty
	public static int COORDS_MENU_CHOICE_USE_GPS_DATA = 3;
	public static int COORDS_MENU_CHOICE_USE_GOOGLEMAPS_DATA = 4;
	public static int COORDS_MENU_CHOICE_MANUAL_ENTRY = 5;

	public static int RETURN_CODE_GMAPS_OK = 0;
	public static int RETURN_CODE_GMAPS_CANCEL = 1;
	
	Context theContext;
	LocationManager locman;	
	Boolean isListenerSet = false;
	Boolean isLocationFix = false;
	
	public static LatitudeLongitude ll_from_GMAPS = new LatitudeLongitude(0.0d, 0.0d);
	
	public void crashDebugAdditionalInformation() {
		ErrorReporter.getInstance().addCustomData("Version", (String)getText(R.string.app_version));
		ErrorReporter.getInstance().addCustomData("Language", (String)getText(R.string.app_language_name));
		ErrorReporter.getInstance().addCustomData("AppStartup.GPSLocation", applicationStartup.currentPosition.toSimplifyString());
		ErrorReporter.getInstance().addCustomData("AppStartup.Time Zone", applicationStartup.currentTimeZone.getDisplayName() + "(" + applicationStartup.currentTimeZone.getID() + ")");
		ErrorReporter.getInstance().addCustomData("Code crash","in coordinatesActivity");
	}

	
    public void savePreferences(){
    	try {
	    	/* Preparation of the save preferences informations */
	    	int mode = Activity.MODE_PRIVATE;
	    		    	
	    	SharedPreferences mySharedPreferences = this.getSharedPreferences(applicationStartup.MYPREFS,mode);
	    	SharedPreferences.Editor editor = mySharedPreferences.edit();
	
	    	//POSITION
	    	editor.putFloat("latitude", (float) applicationStartup.currentPosition.getLatitude());
	    	editor.putFloat("longitude", (float) applicationStartup.currentPosition.getLongitude());
	    	editor.putBoolean("positionSet", applicationStartup.applicationPOSITIONset);
	    	Log.d("Nekloth","PositionSet : " + applicationStartup.applicationPOSITIONset);
	    	editor.commit();

    	} catch (Exception e) {
    		Resources mesRessources = theContext.getResources();
    		String message = mesRessources.getText(R.string.system_error) + e.getMessage();
    		Log.d("Nekloth","Exception : " + message);
    	}
    }    

	
    /**
     * Return the as best as possible location of the terminal.
     * First: GPS location if possible
     * Second: CellID position if possible
     * Otherwise: It is fixed to a particular place 
     *
     * @return      uk.me.jstott.coordconv.LatitudeLongitude
     */
    private LatitudeLongitude getLocation() {
      	 
    	
    		LatitudeLongitude ll = new LatitudeLongitude(0.0d, 0.0d);
    		
        	List<String> providers = locman.getProviders(true);

        	try {
        	
        	for (int i=0 ; i<providers.size(); i++)
        	  	{
        		  String provider = providers.get(i);
        		  //Log.d("Nekloth","Provider : " + provider);
        		  if (provider.compareTo("gps")==0 && !isListenerSet) {
		        		  locman.requestLocationUpdates(provider, 10000, 1000, 
		        	                                           new LocationListener() {
		        			  										public void onLocationChanged(Location location) {isLocationFix = true; updateGPSInfo();}
		        			  										public void onProviderDisabled(String provider){ isLocationFix = false;}
		        			  										public void onProviderEnabled(String provider){updateGPSInfo();}
		        			  										public void onStatusChanged(String provider, int status,  Bundle extras){}
		        	    });
		        		isListenerSet = true;
        		  } //End of IF
        	            	    
        		Location location = locman.getLastKnownLocation(provider);
        	    
        		if (location != null) {
        		  //Log.d("Nekloth","Location is not null (" + ll.toSimplifyString() + ")");
        	      ll.setLatitude(location.getLatitude());
        	      ll.setLongitude(location.getLongitude());
        	    } else {
        	      //Log.d("Nekloth","Location is null. Setup to Notre-Dame de Paris !");
        	      ll.setLatitude(48.854233d);
        	      ll.setLongitude(2.349663d);
        	    }
        	  }
    	} catch (Exception e) {
  	      ll.setLatitude(48.854233d);
	      ll.setLongitude(2.349663d);
	      //Log.d("Nekloth","Exception CATCHED");
    	}
        	  return ll;
    }

    public void updateGPSInfo() {
    	try {
	        ListView myItems = (ListView) findViewById(android.R.id.list);
	        View v = myItems.getChildAt(COORDS_MENU_CHOICE_GPS_LOCATION);
	        
	        TextView aValue = (TextView) v.findViewById(R.id.coord_item_value);
	        aValue.setText(getLocation().toSimplifyString());
	
	        TextView aTitle = (TextView) v.findViewById(R.id.coord_item_title);
	        aTitle.setText(getGPSStatusInfo());
	
	        ImageView anIcon = (ImageView) v.findViewById(R.id.coord_item_icon);
	        anIcon.setImageResource(getGPSIcon());
    	}  catch (Exception e) {
			//crashDebugAdditionalInformation();
			//ErrorReporter.getInstance().handleException(e);
    	}
    }

    public void updateLocationInfo() {
        ListView myItems = (ListView) findViewById(android.R.id.list);
        View v = myItems.getChildAt(COORDS_MENU_CHOICE_SET_LOCATION);
        TextView aValue = (TextView) v.findViewById(R.id.coord_item_value);
        aValue.setText(applicationStartup.currentPosition.toSimplifyString());

        TextView aTitle = (TextView) v.findViewById(R.id.coord_item_title);
        aTitle.setText((String)getText(R.string.coords_set));
        
        savePreferences();
        
    }    
    
    public int getGPSIcon() {
    	if (!isGPSActive()) {
    		return R.drawable.gps_disabled;
    	} else {
	    	if (isGPSFix()) {
	    		return R.drawable.satbase;
	    	} else {
	    		return R.drawable.gps_question;
	    	}
    	}
    }
    

    public String getGPSStatusInfo() {
    	if (isGPSActive()) {
    		return getText(R.string.coords_gps_enabled) + ((isLocationFix)?" "+(String)getText(R.string.coords_and_fixed):" "+(String)getText(R.string.coords_and_not_fixed)) ;
    	} else {
    		return (String) getText(R.string.coords_gps_disabled);
    	}
    	
    }
    
	public boolean isGPSFix() {
		if (isGPSActive()) {
	    	return isLocationFix;
		} else {
			return false;
		}
	}

    
	public boolean isGPSActive() {
		LocationManager locman = (LocationManager) theContext.getSystemService(Context.LOCATION_SERVICE);			
		
    	List<String> providers = locman.getProviders(true);
    	for (int i=0 ; i<providers.size(); i++)
    	  	{
    		  String provider = providers.get(i);
    		  if (provider.compareTo("gps")==0) return true;
    	  	}
    	return false;
	}
	
	
	public void drawActivity(){

    	ArrayList<HashMap<String, Object>> my_coords_list = new ArrayList<HashMap<String, Object>>();

        HashMap<String, Object> coords_map = new HashMap<String, Object>();
        coords_map = new HashMap<String, Object>();
        coords_map.put("coord_item_title", getGPSStatusInfo());
        coords_map.put("coord_item_value", getLocation().toSimplifyString());
        coords_map.put("coord_item_icon", getGPSIcon());
        my_coords_list.add(coords_map);

        coords_map = new HashMap<String, Object>();
        coords_map.put("coord_item_title", (String) getText(R.string.coords_set));
        coords_map.put("coord_item_value", applicationStartup.currentPosition.toSimplifyString());
        coords_map.put("coord_item_icon", R.drawable.coordinates);
        my_coords_list.add(coords_map);

        
        coords_map = new HashMap<String, Object>();
        coords_map.put("coord_item_title", "");
        coords_map.put("coord_item_value", "");
        //coords_map.put("coord_item_icon", R.drawable.coordinates_manual);
        my_coords_list.add(coords_map);

        
        coords_map = new HashMap<String, Object>();
        coords_map.put("coord_item_title", (String)getText(R.string.coords_use_gpsr_information));
        coords_map.put("coord_item_value", (String)getText(R.string.coords_use_gpsr_information_sub));
        coords_map.put("coord_item_icon", R.drawable.coordinates_manual);
        my_coords_list.add(coords_map);

        coords_map = new HashMap<String, Object>();
        coords_map.put("coord_item_title", (String)getText(R.string.coords_use_gmaps));
        coords_map.put("coord_item_value", (String)getText(R.string.coords_use_gmaps_sub));
        coords_map.put("coord_item_icon", R.drawable.coordinates_manual);
        my_coords_list.add(coords_map);

        setContentView(R.layout.coords_activity);

        Typeface face=Typeface.createFromAsset(getAssets(), applicationStartup.GLOBAL_FONT_TO_USE);
	     TextView tv=(TextView)findViewById(R.id.title_coords);
	      tv.setTypeface(face);
        
        ListView myItems = (ListView) findViewById(android.R.id.list);        
        SimpleAdapter monAdapter = new SimpleAdapter(this, my_coords_list, 
      			R.layout.coords_item,
      			new String[] {"coord_item_title", "coord_item_value","coord_item_icon"}, new int[] {R.id.coord_item_title, R.id.coord_item_value, R.id.coord_item_icon});
        
       
        myItems.setAdapter(monAdapter); 
        
        myItems.setOnItemClickListener(new OnItemClickListener() {
          	public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {        		
                  doActionsOnClick(arg1,arg2);
          	}
    		});
        
	}
	 
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (requestCode == applicationStartup.SUB_ACTIVITY_REQUEST_CODE) {
			
			if (resultCode == coordinatesActivity.RETURN_CODE_GMAPS_OK) { //OK
				Log.d("Nekloth","Click OK (LL : "+ll_from_GMAPS.toSimplifyString()+")");
				
	            new AlertDialog.Builder(this)
	            .setTitle(getText(R.string.coords_update_TITLE))
	            .setMessage(getText(R.string.coords_confirm) + "\n" + ll_from_GMAPS.toSimplifyString() + " ?")
	            .setPositiveButton(getText(R.string.yesno_YES), new OnClickListener() {
					@Override
					public void onClick(DialogInterface arg0, int arg1) {
						applicationStartup.currentPosition = ll_from_GMAPS;
						applicationStartup.applicationPOSITIONset = true;
						savePreferences();
						updateLocationInfo();
					}
	            })
	            .setNegativeButton(getText(R.string.yesno_NO),null)
	            .show();
				
			} else { //KO
				//Do nothing
				//Log.d("Nekloth","Click KO, nothing to do");
			} 
			
		}
	}
	
	public void doActionsOnClick(View parentId, int actionToPerform){
		
		if (actionToPerform == COORDS_MENU_CHOICE_GPS_LOCATION) {
			startActivity(new Intent("android.settings.LOCATION_SOURCE_SETTINGS")); 
			}

		if (actionToPerform == COORDS_MENU_CHOICE_USE_GPS_DATA) {
            new AlertDialog.Builder(this)
            .setTitle(getText(R.string.coords_update_TITLE))
            .setMessage(getText(R.string.coords_confirm) + "\n" + getLocation().toSimplifyString() + " ?")
            .setPositiveButton(getText(R.string.yesno_YES), new OnClickListener() {
				@Override
				public void onClick(DialogInterface arg0, int arg1) {
					applicationStartup.currentPosition = getLocation();
					
					applicationStartup.applicationPOSITIONset = true;
					savePreferences();
					updateLocationInfo();
				}
            })
            .setNegativeButton(getText(R.string.yesno_NO),null)
            .show();
		}

        if (actionToPerform == COORDS_MENU_CHOICE_USE_GOOGLEMAPS_DATA) {
        	Intent intent = new Intent();
    		intent.setClass(coordinatesActivity.this, coordinatesGMaps.class);
    		startActivityForResult(intent, applicationStartup.SUB_ACTIVITY_REQUEST_CODE);
    		
		}

	}
	
	public void displayMainHelp() {
	    new AlertDialog.Builder(this)
	      .setTitle(getText(R.string.app_name) + " v." + getText(R.string.app_version))
	      .setPositiveButton(getText(R.string.okcancel_OK), null)
	      .setMessage("" + getText(R.string.help_coords))
	      .show();
	}

	@Override
    public void onWindowFocusChanged(boolean hasFocus) {
		super.onWindowFocusChanged(hasFocus);
		
		if (hasFocus) {
			updateGPSInfo();
		} else {
			// Nothing
		}
	}

    
    public boolean onCreateOptionsMenu(Menu menu) {
    	
        menu.add(0,99,0,(String)getText(R.string.MENU_quick_help))
        	.setIcon(android.R.drawable.ic_menu_help);
        return true;
    }

    public boolean onOptionsItemSelected (MenuItem item){    	
  	  switch (item.getItemId()) {
  	  case 99:
  		  displayMainHelp();
  		  return true;
    	}    	  
  	return false;
  }
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Init
        theContext = this;
    	locman = (LocationManager) theContext.getSystemService(Context.LOCATION_SERVICE);	

        drawActivity();
   }

}
